package gengine.common.packets;

import gengine.common.misc.BaseApplication;

import java.io.*;

/**
 * User: arseniy
 * Date: 21.12.11
 */
public abstract class BasePacket implements Serializable {
    protected int clientId;
    private static final byte START_CODE = 124;
    private static final int END_CODE = 125;

    protected BasePacket(int clientId) {
        this.clientId = clientId;
    }

    public BasePacket() {
    }

    public abstract PacketTypeEnum getPacketType();


    public int getClientId() {
        return clientId;
    }
    
    public void write(ObjectOutputStream stream) throws IOException {
        stream.writeByte(START_CODE);
        stream.writeByte(getPacketType().ordinal());
        stream.writeInt(clientId);
        writeCore(stream);
        stream.writeByte(END_CODE);
    }

    protected abstract void writeCore(ObjectOutputStream stream) throws IOException;

    public static BasePacket read(ObjectInputStream stream) throws PacketParsingException{
        try {
            byte startCode = stream.readByte();
            if (startCode != START_CODE)
                throw new PacketParsingException("Invalid start code");
            byte typeInt = stream.readByte();
            PacketTypeEnum type = PacketTypeEnum.values()[typeInt];
            BasePacket packet = BaseApplication.getApplication().getPacketFactory().create(type);
            packet.clientId = stream.readInt();
            packet.readCore(stream);
            byte endCode = stream.readByte();
            if (endCode!=END_CODE)
                throw new PacketParsingException("Invalid end code");
            return packet;
        } catch (IOException e) {
            throw new PacketParsingException("error during parsing",e);
        }
    }

    protected abstract void readCore(ObjectInputStream stream) throws IOException;


    public void setClientId(int clientId) {
        this.clientId = clientId;
    }
}
